﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CookComputing.Blogger;
using System.Web.UI;
using System.IO;
using GestionNewsLetters.Models.Classes;
using System.Text;

namespace GestionNewsLetters.Models.Dao
{
    /// <summary>
    /// Classe permettant de gérer les newsletters(Création, modification)
    /// Manage newsletters (creation, modification)
    /// </summary>
    public class NewsletterDao
    {
        public NewsletterDao(HttpServerUtility server, string urlApplication)
        {
            //We get the physical paths of the newsletters folders
            //On récupère l'adresse physique du répertoire contenant les newsletters

            //used for unpublished newsletters (accessible to admins only)
            this.path_newsletters = server.MapPath("/_Newsletters");

            //Used for publicated newsletters (accessible to everyone)
            this.pathnewsletters = server.MapPath("/Newsletters");

            this.urlApplication = urlApplication;
        }

        public NewsletterDao(HttpServerUtilityBase server, string urlApplication)
        {
            //We get the physical paths of the newsletters folders
            //On récupère l'adresse physique du répertoire contenant les newsletters
            this.path_newsletters = server.MapPath("/_Newsletters");
            this.pathnewsletters = server.MapPath("/Newsletters");

            this.urlApplication = urlApplication;
        }

        /// <summary>
        /// Créer une nouvelle newsletter
        /// Create a new newsletter.
        /// </summary>
        /// <param name="content">Content of the newsletter (html normally)</param>
        /// <returns>Id of the created newsletter</returns>
        public int Create(Post content)
        {
            return this.Create(content, null);
        }


        /// <summary>
        /// Modifier une newsletter
        /// Modify a newsletter
        /// </summary>
        /// <param name="content">Content of newsletter</param>
        /// <param name="id">Id of the newsletter</param>
        public void Update(Post content, int id)
        {
            this.Create(content, id);
        }

        /// <summary>
        /// Renvoie la liste des newsletters(sans le contenu) en parcourant les dossiers _Newsletters et Newsletters
        /// Returns newsletter list (without content).
        /// </summary>
        /// <returns></returns>
        public List<Newsletter> GetNewsletters()
        {
            //Liste des newsletters
            //Newsletters list
            List<Newsletter> newsletters = new List<Newsletter>();

            DirectoryInfo di_newsletters = new DirectoryInfo(this.path_newsletters);
            DirectoryInfo dinewsletters = new DirectoryInfo(this.pathnewsletters);

            //We only look for file ending with ".html"
            //On ne cherche que les fichiers qui finissent en ".html"
            foreach (FileInfo file in di_newsletters.GetFiles("*.html"))
            {
                //On supprime le ".html"
                //We delete ".html"
                newsletters.Add(new Newsletter() { Id = int.Parse(file.Name.Substring(0,file.Name.IndexOf("."))), Etat = EtatNewsletter.En_attente });
            }

            foreach (FileInfo file in dinewsletters.GetFiles("*.html"))
            {
                newsletters.Add(new Newsletter() { Id = int.Parse(file.Name.Substring(0, file.Name.IndexOf("."))), Etat = EtatNewsletter.Envoye });
            }

            return newsletters;
        }

        /// <summary>
        /// Renvoie une newsletter AVEC le contenu en parcourant le dossier _Newsletters(newsletters non publiées)
        /// et transfère la newsletter dans le dossier Newsletters si deplacer = true
        /// Returns an unpublished newsletter WITH its content. Transfers it to published folder if deplacer = true
        /// </summary>
        /// <returns></returns>
        public Newsletter GetNewsletterForPublication(int idNewsletter,bool deplacer)
        {
            string filePath = this.path_newsletters + "/" + idNewsletter + ".html";
            string publicatedFilePath = this.pathnewsletters + "/" + idNewsletter + ".html";

            Newsletter newsletter = new Newsletter()
            {
                Id = idNewsletter,
                Etat = EtatNewsletter.Envoye
            };

            if(File.Exists(filePath))
                newsletter.Contenu = File.ReadAllText(filePath, Encoding.UTF8);

                //Exception si le fichier n'est pas trouvé.
                //Exception triggered if file not found
            else
            {
                if(File.Exists(publicatedFilePath))
                    throw new FileNotFoundException("Le fichier " + filePath + "n'a pas été trouvé."
                        + "Par contre le fichier " + publicatedFilePath + " existe. Ce qui veut dire que cette newsletter a déjà été publiée:"
                        + "impossible de republier une newsletter... désolé.");
                else

                throw new FileNotFoundException("Le fichier " + filePath + "n'a pas été trouvé. La newsletter n'existe pas non plus à cette adresse:"
                    + publicatedFilePath);
            }

            //On déplace la newsletter dans le dossier des newsletters envoyées is deplacer = true
            //We move the newsletter if deplacer = true (deplacer means move).
            if (deplacer)
            {
                File.Delete(publicatedFilePath);
                File.Move(filePath, publicatedFilePath);
            }

            return newsletter;
        }


        /// <summary>
        /// Crée une nouvelle newsletter (ou la modifie si son id existe)
        /// Create a new newsletter (or modify it if it exists already)
        /// </summary>
        /// <param name="content"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        private int Create(Post content, int? id)
        {
            //On récupère l'adresse physique du répertoire contenant les newsletters
            //We get the physical path of the newsletters directory.
            string PhysicalPath = this.path_newsletters;


            if (id == null)
                //On compte le nombre de fichiers dans les dossiers pour en déduire l'id de la newsletter
                //We count files in both folders to find out wich is the id of this one
                id = Directory.GetFiles(this.pathnewsletters).Length + Directory.GetFiles(PhysicalPath).Length + 1;
            //Si on veut modifier une newsletter, il faut qu'elle n'est pas été publiée
                //If we want to modify a newsletter, it has to be unpublicated
            else if (File.Exists(this.pathnewsletters + "/" + id + ".html"))
                throw new Exception("Impossible de modifier une newsletter déjà publiée.");

            //Adresse du fichier sur le serveur
            //Adress of the newsletter file on the server
            string adresseFile = PhysicalPath + "/" + id + ".html";

            //On crée/écrase le fichier correspondant à l'ID
            //We create/delete and recreate the file corresponding to the id
            using(FileStream fileStream = File.Open(adresseFile, FileMode.Create, FileAccess.ReadWrite))
            {
                //On écrit dans le fichier
                //We write in the file
                using(StreamWriter writer = new StreamWriter(fileStream))
                {
                    //Please note: some "{" below are used only for presentation (not needed).


                    HtmlTextWriter html = new HtmlTextWriter(writer);
                    {
                        html.Write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
                        html.RenderBeginTag(HtmlTextWriterTag.Html);
                        {
                            //Header
                            html.RenderBeginTag(HtmlTextWriterTag.Head);
                            {
                                html.Write("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />");

                                //html.RenderBeginTag(HtmlTextWriterTag.Title);
                                {
                                    html.Write("<title>" + content.title + "</title>");
                                }
                                //html.RenderEndTag();
                            }
                            html.RenderEndTag();


                            //body
                            html.RenderBeginTag(HtmlTextWriterTag.Body);
                            {
                                //On affiche un lien de désinscription et un lien pour voir la newsletter sur le site
                                //On remplace: "[newsletter]". "[desinscription]" n'est pas commun à tous le monde: on ne le remplace pas là

                                //Replaces [newsletter] (link to the publicated newsletter) and [desinscription] (unsubscribe link)

                                 content.description = content.description.Replace("[newsletter]", this.urlApplication + "/Newsletters/" + id.Value + ".html");

                                 int position = content.description.IndexOf("[desinscription]");
                                 if (position >= 0)
                                     content.description = content.description.Insert(position, this.urlApplication + "/Newsletter/Inscription?");

                                html.Write(content.description);
                                

                                
                            }
                            html.RenderEndTag();
                        }
                        html.RenderEndTag();
                    }
                    html.Flush();
                }
            }

            return id.Value;
        }

        private string path_newsletters;
        private string pathnewsletters;
        private string urlApplication;

    }
}